// 把原有缓存大小进行了分片。
#include "LRU_K.h"
#include <vector>
#include <cmath>

// lru优化：对lru进行分片，提高高并发使用的性能
// 每个分片都具有“主缓存”和“历史缓存”，默认历史缓存大小是主缓存的1.5倍
template<typename Key, typename Value>
class HashLruKCaches
{
public:
    HashLruKCaches(size_t capacity, int sliceNum, int k) //
    : m_capacity(capacity)
    , m_sliceNum(sliceNum > 0 ? sliceNum : 3)
    {
        size_t sliceSize = std::ceil(capacity / static_cast<double>(m_sliceNum)); // 每个分片的大小（向上取整）
        for (int i = 0; i < m_sliceNum; ++i){
            // 默认历史缓存为主缓存的1.5倍
            m_lruSliceCaches.emplace_back(new LruKCache<Key, Value>(sliceSize, sliceSize*1.5, k)); 
        }
    }

    void put(const Key& key, const Value& value)
    {
        // 获取key的hash值，并计算出对应的分片索引
        size_t sliceIndex = Hash(key) % m_sliceNum;
        m_lruSliceCaches[sliceIndex]->put(key, value);
    }

    bool get(const Key& key, Value& value)
    {
        // 获取key的hash值，并计算出对应的分片索引
        size_t sliceIndex = Hash(key) % m_sliceNum;
        return m_lruSliceCaches[sliceIndex]->get(key, value);
    }

    Value get(Key key)
    {
        Value value;
        memset(&value, 0, sizeof(value));
        get(key, value);
        return value;
    }

private:
    // 将key转换为对应hash值
    size_t Hash(Key key)
    {
        return m_hashFunc(key);
    }

private:
    size_t                                              m_capacity;  // 总容量
    int                                                 m_sliceNum;  // 切片数量
    std::vector<std::unique_ptr<LruKCache<Key, Value>>> m_lruSliceCaches; // 切片LRU缓存
    std::hash<Key>                                      m_hashFunc;  // 哈希计算器
};